#include "mainproc.h"


void led_work_flicker( void )
{
  uint32_t timeout = 0;
  if( BOOTLOADER )
  {
    timeout = LED_Flicker_Cycle * 0.5f;
  }
  else
  {
    timeout = LED_Flicker_Cycle;
  }
  if( rk.timer.led_work_timer >= timeout )
  {
    GPIO_LED_1_MCU_Toggle;
    GPIO_LED_Toggle;

    rk.timer.led_work_timer = 0;
  }
}

void software_reset( void )
{
  __set_FAULTMASK(1);
  HAL_NVIC_SystemReset();
}

void check_system_status( void )
{
  if( rk.timer.sensor_water_level_timer >= Sensor_Never_Data_Timer_Max )
  {
    rk.timer.sensor_water_level_timer = 0;
    switch( RK_PROJECT )
    {
      case XY_PROJECT :
        GPIO_P24V_Water_EN_RESET;
        GPIO_MCU_WDI_Toggle;
        HAL_Delay(1200);
        GPIO_MCU_WDI_Toggle;
        HAL_Delay(1200);
        GPIO_P24V_Water_EN_SET;
        break;

      case ATMT_ONE_CULUMN_PROJECT :
        GPIO_P12V_Water_EN_RESET;
        GPIO_MCU_WDI_Toggle;
        HAL_Delay(1200);
        GPIO_MCU_WDI_Toggle;
        HAL_Delay(1200);
        GPIO_P12V_Water_EN_SET;
        break;

      case ATMT_TWO_CULUMN_PROJECT :
        GPIO_P12V_Water_EN_RESET;
        GPIO_MCU_WDI_Toggle;
        HAL_Delay(1200);
        GPIO_MCU_WDI_Toggle;
        HAL_Delay(1200);
        GPIO_P12V_Water_EN_SET;
        break;

      default :

        break;
    }
    rk.timer.sensor_water_level_timer = 0;
  }
  if( rk.timer.sensor_flowmeter_timer >= Sensor_Never_Data_Timer_Max )
  {
    rk.timer.sensor_flowmeter_timer = 0;
    switch( RK_PROJECT )
    {
      case XY_PROJECT :

        break;

      case ATMT_ONE_CULUMN_PROJECT :
        GPIO_P12V_Flow_EN_RESET;
        GPIO_MCU_WDI_Toggle;
        HAL_Delay(1200);
        GPIO_MCU_WDI_Toggle;
        HAL_Delay(1200);
        GPIO_P12V_Flow_EN_SET;
        break;

      case ATMT_TWO_CULUMN_PROJECT :
        GPIO_P12V_Flow_EN_RESET;
        GPIO_MCU_WDI_Toggle;
        HAL_Delay(1200);
        GPIO_MCU_WDI_Toggle;
        HAL_Delay(1200);
        GPIO_P12V_Flow_EN_SET;
        break;

      default :

        break;
    }

  }
  if( rk.flag.system_restart == true )
  {
    if( rk.flash_cycle_queue.head < rk.flash_cycle_queue.tail )
    {
      from_exflash_read_package( &rk.flash_cycle_queue );
      EC20_send_data( rk.flash_cycle_queue.read_data, rk.flash_cycle_queue.read_len );
    }
    rk.timer.RS485_transmit_timer = 0;
    while( !__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC) )
    {
      if( rk.timer.RS485_transmit_timer >= RS485_Transmit_Timeout )
      {
        break;
      }
    }
    GPIO_MCU_WDI_Toggle;
    HAL_Delay(1200);
    GPIO_MCU_WDI_Toggle;
    EC20_send_str( "+++" );
    HAL_Delay(1200);
    GPIO_MCU_WDI_Toggle;
    EC20_send_str( array_QICLOSE );
    uart_log("system restart!\r\n");
    HAL_Delay(1200);
    GPIO_MCU_WDI_Toggle;
    software_reset();
  }
}

// EC20 一段时间没接收到数据 -> 关机， 关机一段时间后 -> 启动
void check_EC20_status( void )
{
  if( rk.CONFIG.EC20 == disable )
  {
    return;
  }
  if( rk.timer.EC20_stop_work_timer >= rk.hyper_parameter.reconnect_server_timer * A_Second )
  {
    GPIO_P3V8_EN_SET;
    rk.flag.EC20_shutdown = true;
    rk.timer.EC20_stop_work_timer = 0;
    uart_log("EC20 recv timeout!\r\n");
  }
  if( rk.flag.EC20_shutdown )
  {
    if( rk.timer.EC20_shutdown_timer >= EC20_Shutdown_Timer_Max )
    {
      GPIO_P3V8_EN_RESET;
      rk.flag.system_restart = true;
      rk.timer.EC20_shutdown_timer = 0;
      rk.flag.EC20_shutdown = false;
    }
  }
}

void get_sensor_vaule( void )
{
  if(rk.timer.get_sensor_value_timer >= Get_Sensor_Value_Timer_Max )
  {
    rk.timer.get_sensor_value_timer = 0;

    if( rk.CONFIG.FLOWMETER == okey )
    {
      /* water_level  flowmeter */
      get_water_correlation_value( RK_PROJECT, XY_BOTH_GET_SD );
    }
    if( rk.CONFIG.DS18B20 == okey )
    {
      /* ds18b20 */
      rk.ds18b20.temperature = DS18B20_Read_Temperature();
    }
    if( rk.CONFIG.INA226 == okey )
    {
      /* INA226 */
      get_power_data( RK_PROJECT, &hi2c1, &rk.ina226 );
    }
    if( rk.CONFIG.ENCODER == okey )
    {
      /* encoder */
      get_encoder_value(RK_PROJECT);
    }
  }

  if( rk.flag.recv_XY_flowmeter )
  {
    recv_XYflowmeter_package_handle();
    rk.flag.recv_XY_flowmeter = false;
  }
  if( rk.flag.recv_XY_ABCencoder )
  {
    recv_XY_ABSencoder_package_handle();
    rk.flag.recv_XY_ABCencoder = false;
  }
  if( rk.flag.recv_ATMT_flowmeter )
  {
    recv_ATMTflowmeter_package_handle();
    rk.flag.recv_ATMT_flowmeter = false;
  }
  if( rk.flag.recv_ATMT_ABSencoder )
  {
    recv_ATMT_ABSencoder_package_handle();
    rk.flag.recv_ATMT_ABSencoder = false;
  }
  if( rk.flag.recv_ATMT_motor_driver )
  {
    recv_ATMT_motor_driver_package_handle();
    rk.flag.recv_ATMT_motor_driver = false;
  }
}

uint8_t judge_gate_which_stop( void )
{
  char str[88];
  if( rk.flag.gate_move_to_limit == false )
  {
    // 闸门运动到极限值后停止运动 并进行上报
    if( rk.ina226.current_outcnt > 1 )
    {
      rk.flag.gate_move_to_limit = true;
      upload_package = upload_gate_move_limit_package;
      upload_package_init();
      upload_package_crc_end( upload_package() );
      sprintf(str, "gate move to limit, current out, encoder value : %d current : %f\r\n", rk.encoder.turn_nums, rk.ina226.current );
      uart_log( str );
      return 3;
    }
    else if( (RK_PROJECT == XY_PROJECT) && (rk.timer.encoder_recv_stop_timer >= 2 * A_Second) )
    {
      rk.flag.gate_move_to_limit = true;
      motor_rotate_stop();
      uart_log( "gate don`t move, lose encoder data!\r\n" );
      return 4;
    }
  }
  return 0;
}

/* 闸门控制 */
void control_gate( void )
{
  /* 分析闸门运动 */
  analyse_gate_move();

  /* 判断闸门是否要停止 */
  if( !judge_gate_which_stop() )
  {

    // 选择手动或者自动方式控制闸门
    if( rk.timer.gate_control_timer >= Gate_Control_Timer_Max )
    {
      rk.timer.gate_control_timer = 0;
      if( rk.flag.gate_move_to_limit == true )
      {
        motor_rotate_stop();
      }
      else
      {
        if( rk.parameter.control_mode == Manual_Control_Mode )
        {
          manual_control_gate();
        }
        else if( rk.parameter.control_mode == Auto_Control_Mode )
        {
          auto_control_gate();
        }
      }
    }
  }
}
/* 风扇控制 */
void control_fan( void )
{
  if( rk.ds18b20.temperature >= rk.hyper_parameter.temperature_upper_limit )
  {
    GPIO_FAN_EN_SET;
  }
  else
  {
    GPIO_FAN_EN_RESET;
  }
}
void control_task( void )
{
  /* 闸门控制 */
  control_gate();

  /* 风扇控制 */
  control_fan();
}

void get_server_data( void )
{
  // timer out -> reset
  check_EC20_status();

  // recive -> handle
  if( rk.flag.recv_EC20 == true )
  {
    recv_EC20_package_handle();
  }
}

void calibration_system_parameter( void )
{
  static int calibration_step = 0;
  char str[32];
//  set_water_level_gauge_id( rk.hyper_parameter.gata_front_water_stage_addr );

//  motor_study();
  // 校准电机
  while(1)
  {
    if(rk.timer.get_sensor_value_timer >= Get_Sensor_Value_Timer_Max )
    {
      GPIO_MCU_WDI_Toggle;
      rk.timer.get_sensor_value_timer = 0;

      /* encoder */
      get_encoder_value(RK_PROJECT);
      /* INA226 */
      get_power_data( RK_PROJECT, &hi2c1, &rk.ina226 );
    }
    // 步骤一 ：将闸门运动到最低端
    if( calibration_step == 0 )
    {
      if( rk.timer.gate_control_timer > Gate_Control_Timer_Max )
      {
        rk.timer.gate_control_timer  = 0;
        control_motor_move( NULL, RK_PROJECT, DOWN );
        if( rk.ina226.current_outcnt > 1 )
        {
          motor_rotate_stop();
          calibration_step++;
          uart_log("calibration step1 complete, ");

          sprintf(str, "current : %.3f\r\n",rk.ina226.current );
          uart_log( str );
          rk.ina226.current_outcnt = 0;
        }
      }
    }

    // 步骤二：将当前的增量式编码值清零后，上升到最顶端
    else if( calibration_step == 1 )
    {
      rk.flag.gate_move_to_limit = false;
      HAL_Delay(1000);
      GPIO_MCU_WDI_Toggle;
       HAL_Delay(1000);
      rk.hyper_parameter.encoder_lower_limit = rk.encoder.turn_nums;
      if( rk.timer.gate_control_timer > Gate_Control_Timer_Max )
      {
        rk.timer.gate_control_timer  = 0;
        control_motor_move( NULL, RK_PROJECT, UP );
        if( rk.ina226.current_outcnt > 1 )
        {
          motor_rotate_stop();
          calibration_step++;
          uart_log("calibration step2 complete!\r\n");
        }
      }
    }

    // 步骤三：记录当前增量式编码值，计算出角度和位移的系数
    else if( calibration_step == 2 )
    {
      rk.hyper_parameter.encoder_upper_limit = rk.encoder.turn_nums;
      rk.hyper_parameter.angle_to_displacement_coefficient = (float)rk.hyper_parameter.gate_height / ((float)rk.hyper_parameter.encoder_upper_limit - (float)rk.hyper_parameter.encoder_lower_limit);
      initflag_set( Extflash_Init_Flag );
      HAL_Delay(20);
      hyper_parameter_set();
      HAL_Delay(20);
      parameter_set();
      HAL_Delay(20);
      uart_log("calibration step3 complete!\r\n");
      break;
    }
  }
}

void check_uartcom_set( void )
{
  if( rk.flag.recv_set_parameter )
  {
    recv_set_parameter_package_handle();
    rk.flag.recv_set_parameter = false;
  }
}

void mainproc( void )
{
  /* led闪烁 */
  led_work_flicker();

  /* 检查系统是否要重启 */
  check_system_status();

  /* 检查上位机是否配置参数 */
  check_uartcom_set();

  /* 获取服务器的数据 */
  get_server_data();

  /* 获取传感器的值 */
  get_sensor_vaule();

  /* 控制任务 */
  control_task();

  /* 刷新串口屏数据 */
  refresh_screen_data();

  /* 上传数据至服务器 */
  upload_data_to_server();
}
